﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Data.SQLite;

namespace Stone
{
    public partial class FormMain : Form
    {
        //COMMON
        private DB db = new DB(Settings.DB_Osm_Path);

        public FormMain()
        {
            InitializeComponent();
        }
        private void FormMain_Load(object sender, EventArgs e)
        {
            Settings.LoadSettings();
            timerSystemPerformance.Start();
            cam.LoadDevices();
            comboBox_CamDevices.Items.AddRange(cam.devices);

            foreach (DirectoryInfo tmp in GlobalFunctions.GetSkinsList())
                comboBox_DefaultSkin.Items.Add(tmp.Name);

            tabControl_Main.SelectTab("tabPage_Gps");

            //webBrowser_OSM.Url = new Uri("http://www.openstreetmap.org/?minlon=22.3418234&minlat=57.5129102&maxlon=22.5739625&maxlat=57.6287332&box=yes");

            webKitBrowser1.Url = new Uri("http://www.openstreetmap.org/?minlon=22.3418234&minlat=57.5129102&maxlon=22.5739625&maxlat=57.6287332&box=yes");

            //GPS_comboBox_ComPort.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            GPS_comboBox_ComPort.SelectedItem = Settings.GPS_ComPort;
            GPS_comboBox_Baudrate.SelectedItem = Settings.GPS_ComPort_Baudrate;

            comboBox_DefaultSkin.SelectedItem = Settings.Skin_Name;

            GpsHandler = new GPSHandler(this);
            GpsHandler.NewGPSFix += new GPSHandler.NewGPSFixHandler(this.GPSEventHandler);

            MapDescription testMapDescription = new MapDescription();
            testMapDescription.name = "Test_map";
            testMapDescription.lastUpdate = DateTime.Now;
            testMapDescription.size = 2000;

            serializeMapDescription("MapDescription.xml", testMapDescription);
        }
        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            Settings.SaveSettings();
        }
        private void timerSystemPerformance_Tick(object sender, EventArgs e)
        {
            Process proc = Process.GetCurrentProcess();
            long valore = proc.PagedMemorySize64 / 1024 / 1024;
            this.Text = "Stone Configurator - Used RAM: " + valore + " Mb";
        }
        private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            FormPassword f = new FormPassword();

            if (f.ShowDialog() == DialogResult.OK)
            {
                this.Visible = true;
            }
        }
        private void buttonMinimize_Click(object sender, EventArgs e)
        {
            this.Visible = false;
        }
        private void tabControl_Gps_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl_Gps.SelectedTab.Name == "tabPage_Gps_Maps_Upload_Download")
            {
                FtpRefreshClientList();
                ftpServer.url = "ftp.onlyonemillion.com";
                ftpServer.username = "2334698@aruba.it";
                ftpServer.password = "vdd4fmyd";
                FtpConnect(ftpServer);
            }
            else
            {
                FtpDisconnect();
            }
        }

        private void Log(string text)
        {
            File.AppendAllText(Settings.LOG_Path, DateTime.Now.ToString() + " " + text + "\n\r\n\r");
        }


        //CAM
        private Module_Cam cam = new Module_Cam();

        private void comboBox_CamDevices_SelectedIndexChanged(object sender, EventArgs e)
        {
            Device d = DeviceManager.GetDevice(comboBox_CamDevices.SelectedIndex);
            cam.AttachToControl(d, pictureBox_CamDevicePreview);
        }


        //SKIN
        private void comboBox_DefaultSkin_SelectedIndexChanged(object sender, EventArgs e)
        {
            Settings.Skin_Name = comboBox_DefaultSkin.SelectedItem.ToString();
        }


        //GPS - Antenna
        public GPSHandler GpsHandler;

        private void GPS_comboBox_ComPort_SelectedIndexChanged(object sender, EventArgs e)
        {
            Settings.GPS_ComPort = GPS_comboBox_ComPort.SelectedItem.ToString();
        }
        private void GPS_comboBox_Baudrate_SelectedIndexChanged(object sender, EventArgs e)
        {
            Settings.GPS_ComPort_Baudrate = GPS_comboBox_Baudrate.SelectedItem.ToString();
        }
        private void button_GPS_Antenna_Test_Click(object sender, EventArgs e)
        {
            GpsHandler.Start(Settings.GPS_ComPort, int.Parse(Settings.GPS_ComPort_Baudrate));
            button_GPS_Antenna_Test.Enabled = false;
            button_GPS_Antenna_Test_STOP.Enabled = true;
        }
        private void button_GPS_Antenna_Test_STOP_Click(object sender, EventArgs e)
        {
            GpsHandler.Stop();
            button_GPS_Antenna_Test.Enabled = true;
            button_GPS_Antenna_Test_STOP.Enabled = false;
        }
        private void GPSEventHandler(object sender, GPSHandler.GPSEventArgs e)
        {
            ReceiveNMEA(GpsHandler, e);
        }
        public void ReceiveNMEA(GPSHandler GpsHandler, GPSHandler.GPSEventArgs e)
        {
            //MessageBox.Show(e.TypeOfEvent.ToString());


            switch (e.TypeOfEvent)
            {
                case GPSEventType.TimeOut:

                    break;

                case GPSEventType.GPRMC:  //Recommended minimum specific GPS/Transit data

                    richTextBox_GPS_NMEA_log.Text += GpsHandler.GPRMC.NMEA_string + "\n";
                    label_GPRMC.Text = GpsHandler.GPRMC.NMEA_string;

                    if (GpsHandler.HasGPSFix) //Is a GPS fix available?
                    {
                        //osmMap.CAR_timeOfFix = GpsHandler.GPRMC.TimeOfFix;
                        //osmMap.CAR_course = GpsHandler.GPRMC.Course;

                        float Lon = (float)GpsHandler.GPRMC.Position.Longitude;
                        float Lat = (float)GpsHandler.GPRMC.Position.Latitude;

                        //osmMap.SetCarPosition(new PointF(Lon, Lat));
                        //osmMap.CAR_speed = GpsHandler.GPRMC.Speed;
                    }
                    break;

                case GPSEventType.GPGSV:

                    richTextBox_GPS_NMEA_log.Text += GpsHandler.GPGSV.NMEA_string + "\n";
                    label_GPGSV.Text = GpsHandler.GPGSV.NMEA_string;

                    //satellites = GpsHandler.GPGSV.Satellites;
                    //visibleSatellites = GpsHandler.GPGSV.SatsInView;
                    break;
            }
        }


        //GPS - CREATE MAPS
        private Thread threadLoading = null;
        private Thread threadConvertingTables = null;
        delegate void SetButtonGO_LoadFile_enabledCallback(bool value);
        delegate void SetButtonStop_LoadFile_EnabledCallback(bool value);
        delegate void SetProgressbar_LoadFile_Callback(int value);
        delegate void SetProgressbar_LoadFile_MaximumCallback(int value);
        delegate void SetMessage_LoadFile_TextCallback(string text);
        delegate void SetLabelNodesCount_LoadFile_TextCallback(string text);
        delegate void SetLabelTimeToFinish_LoadFile_TextCallback(string text);
        delegate void SetButtonGO_ConvertTables_enabledCallback(bool value);
        delegate void SetButtonStop_ConvertTables_EnabledCallback(bool value);
        delegate void SetProgressbar_ConvertTables_Callback(int value);
        delegate void SetProgressbar_ConvertTables_MaximumCallback(int value);
        delegate void SetMessage_ConvertTables_TextCallback(string text);

        private void SetButtonGO_LoadFile_enabled(bool value)
        {
            if (this.progressBarGO_LoadFile.InvokeRequired)
            {
                SetButtonGO_LoadFile_enabledCallback d = new SetButtonGO_LoadFile_enabledCallback(SetButtonGO_LoadFile_enabled);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.buttonGO_LoadFile.Enabled = value;
            }
        }
        private void SetButtonStop_LoadFile_Enabled(bool value)
        {
            if (this.progressBarGO_LoadFile.InvokeRequired)
            {
                SetButtonStop_LoadFile_EnabledCallback d = new SetButtonStop_LoadFile_EnabledCallback(SetButtonStop_LoadFile_Enabled);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.buttonStop_LoadFile.Enabled = value;
            }
        }
        private void SetProgressbar_LoadFile(int value)
        {
            if (this.progressBarGO_LoadFile.InvokeRequired)
            {
                SetProgressbar_LoadFile_Callback d = new SetProgressbar_LoadFile_Callback(SetProgressbar_LoadFile);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.progressBarGO_LoadFile.Value = value;
            }
        }
        private void SetProgressbarMaximum_LoadFile(int value)
        {
            if (this.progressBarGO_LoadFile.InvokeRequired)
            {
                SetProgressbar_LoadFile_MaximumCallback d = new SetProgressbar_LoadFile_MaximumCallback(SetProgressbarMaximum_LoadFile);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.progressBarGO_LoadFile.Maximum = value;
            }
        }
        private void SetLabelMessage_LoadFile(string text)
        {
            if (this.labelMessage_LoadFile.InvokeRequired)
            {
                SetMessage_LoadFile_TextCallback d = new SetMessage_LoadFile_TextCallback(SetLabelMessage_LoadFile);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.labelMessage_LoadFile.Text = text;
            }
        }
        private void SetLabelNodesCount_LoadFile(string text)
        {
            if (this.labelNodesCount_LoadFile.InvokeRequired)
            {
                SetLabelNodesCount_LoadFile_TextCallback d = new SetLabelNodesCount_LoadFile_TextCallback(SetLabelNodesCount_LoadFile);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.labelNodesCount_LoadFile.Text = text;
                //this.labelNodesCount.Refresh();
            }
        }
        private void SetLabelTimeToFinish_LoadFile(string text)
        {
            if (this.labelNodesCount_LoadFile.InvokeRequired)
            {
                SetLabelTimeToFinish_LoadFile_TextCallback d = new SetLabelTimeToFinish_LoadFile_TextCallback(SetLabelTimeToFinish_LoadFile);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.labelEstimatedTimeToFinish_LoadFile.Text = text;
            }
        }
        private void SetButtonGO_ConvertTables_enabled(bool value)
        {
            if (this.progressBar_CovertingTables.InvokeRequired)
            {
                SetButtonGO_ConvertTables_enabledCallback d = new SetButtonGO_ConvertTables_enabledCallback(SetButtonGO_ConvertTables_enabled);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.button_Go_convertingTables.Enabled = value;
            }
        }
        private void SetButtonStop_ConvertTables_Enabled(bool value)
        {
            if (this.progressBar_CovertingTables.InvokeRequired)
            {
                SetButtonStop_ConvertTables_EnabledCallback d = new SetButtonStop_ConvertTables_EnabledCallback(SetButtonStop_ConvertTables_Enabled);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.buttonStop_ConvertingTable.Enabled = value;
            }
        }
        private void SetProgressbar_ConvertTables(int value)
        {
            if (this.progressBar_CovertingTables.InvokeRequired)
            {
                SetProgressbar_ConvertTables_Callback d = new SetProgressbar_ConvertTables_Callback(SetProgressbar_ConvertTables);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.progressBar_CovertingTables.Value = value;
            }
        }
        private void SetProgressbarMaximum_ConvertTables(int value)
        {
            if (this.progressBar_CovertingTables.InvokeRequired)
            {
                SetProgressbar_ConvertTables_MaximumCallback d = new SetProgressbar_ConvertTables_MaximumCallback(SetProgressbarMaximum_ConvertTables);
                this.Invoke(d, new object[] { value });
            }
            else
            {
                this.progressBar_CovertingTables.Maximum = value;
            }
        }
        private void SetLabelMessage_ConvertTables(string text)
        {
            if (this.labelMessage_LoadFile.InvokeRequired)
            {
                SetMessage_ConvertTables_TextCallback d = new SetMessage_ConvertTables_TextCallback(SetLabelMessage_ConvertTables);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.label_Message_ConvertingTables.Text = text;
            }
        }

        private void buttonBrowseSourceFile_Click(object sender, EventArgs e)
        {
            openFileDialogOSMdata.InitialDirectory = Settings.Maps_Path;

            if (openFileDialogOSMdata.ShowDialog() == DialogResult.OK)
            {
                textBoxPathToOSMdata.Text = openFileDialogOSMdata.FileName;
                groupBoxProgress.Enabled = true;
                labelFilesize_LoadFile.Text = "Filesize: " + GlobalFunctions.GetFileSizeString(textBoxPathToOSMdata.Text);
                buttonGO_LoadFile.Enabled = true;
            }
        }
        private void buttonStop_Click(object sender, EventArgs e)
        {
            threadLoading.Abort();
            buttonGO_LoadFile.Enabled = true;
            buttonStop_LoadFile.Enabled = false;
            SetLabelMessage_LoadFile("Press button to GO!...");
        }
        private void buttonGO_Click(object sender, EventArgs e)
        {
            buttonGO_LoadFile.Enabled = false;
            buttonStop_LoadFile.Enabled = true;
            progressBarGO_LoadFile.Minimum = 0;
            progressBarGO_LoadFile.Maximum = 1000000;

            ThreadStart job = new ThreadStart(Load_OSM_File_Into_DB_new);
            threadLoading = new Thread(job);
            threadLoading.Start();
        }
        private void button_Go_convertingTables_Click(object sender, EventArgs e)
        {
            ThreadStart job = new ThreadStart(ConvertingTables);
            threadConvertingTables = new Thread(job);
            threadConvertingTables.Start();
        }
        private void buttonStop_ConvertingTable_Click(object sender, EventArgs e)
        {
            threadConvertingTables.Abort();
            button_Go_convertingTables.Enabled = true;
            buttonStop_ConvertingTable.Enabled = false;
            SetLabelMessage_ConvertTables("Press button to GO!...");
        }
        private void button_ImportKML_Click(object sender, EventArgs e)
        {
            if (openFileDialog_ImportKML.ShowDialog() == DialogResult.OK)
            {
                ImportKML(openFileDialog_ImportKML.FileName);
            }
        }

        private void Load_OSM_File_Into_DB_new()
        {
            int ProgressbarCounter = 0;
            int step1Counter = 0;
            int step2Counter = 0;

            if (!this.DesignMode)
            {
                try
                {
                    #region Open DB and transaction
                    db.Connect();
                    db.BeginTransaction();
                    #endregion

                    #region Delete all tables records
                    db.ExecuteNonQuery("DELETE FROM ways_full;");
                    db.ExecuteNonQuery("DELETE FROM nodes;");
                    db.ExecuteNonQuery("DELETE FROM ways;");
                    db.ExecuteNonQuery("DELETE FROM node_tags;");
                    db.ExecuteNonQuery("DELETE FROM way_tags;");
                    db.ExecuteNonQuery("DELETE FROM way_nodes;");
                    #endregion

                    #region Estimating time to finish
                    SetLabelMessage_LoadFile("Estimating time to finish...");
                    int NodesCount = File_OSM_Statistics();
                    SetLabelMessage_LoadFile("Loading file into DB...");
                    SetProgressbarMaximum_LoadFile(NodesCount);
                    SetLabelNodesCount_LoadFile("Nodes count: 0/" + NodesCount.ToString());
                    #endregion

                    #region Opening files
                    XmlReader reader = XmlReader.Create(textBoxPathToOSMdata.Text);
                    StreamWriter swStep1 = new StreamWriter(Settings.BulkSQL_Step1_Path);
                    StreamWriter swStep2 = new StreamWriter(Settings.BulkSQL_Step2_Path);
                    #endregion

                    string idParentNode = "-1";
                    DateTime startTime = DateTime.Now;

                    #region Read Osm File

                    while (reader.Read())
                    {
                        #region Progressbar updating
                        if (((ProgressbarCounter % 100) == 1) || (ProgressbarCounter >= progressBarGO_LoadFile.Maximum))
                        {
                            SetProgressbar_LoadFile(ProgressbarCounter);
                            TimeSpan timeLocalExecution = DateTime.Now - startTime;
                            long totalTicks = NodesCount * timeLocalExecution.Ticks / ProgressbarCounter;
                            long ticksToFinish = totalTicks - timeLocalExecution.Ticks;
                            TimeSpan timeToFinish = new TimeSpan(ticksToFinish);
                            SetLabelTimeToFinish_LoadFile("Estimated time to finish: " + timeToFinish.ToString());
                            SetLabelNodesCount_LoadFile("Nodes count: " + ProgressbarCounter + "/" + NodesCount.ToString());
                        }
                        #endregion

                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            #region Nodes
                            if (reader.Name == "node")
                            {
                                idParentNode = reader.GetAttribute("id");
                                string lon = reader.GetAttribute("lon");
                                string lat = reader.GetAttribute("lat");

                                string q = "INSERT INTO nodes (id, lon, lat) VALUES (\"" + idParentNode + "\",\"" + lon + "\",\"" + lat + "\");";
                                db.ExecuteNonQuery(q);

                                string q6 = "UPDATE ways_full SET node_lat = '" + lat + "', node_lon = '" + lon + "' WHERE id_node = '" + idParentNode + "';";
                                swStep2.WriteLine(q6);
                                step2Counter++;

                                XmlReader readerChilds = reader.ReadSubtree();

                                while (readerChilds.Read())
                                {
                                    if (readerChilds.Name == "tag")
                                    {
                                        string q1 = "INSERT INTO node_tags (ref, key, value) VALUES (\"" + idParentNode + "\",\"" + readerChilds.GetAttribute("k").Replace("\"", "") + "\",\"" + readerChilds.GetAttribute("v").Replace("\"", "") + "\");";
                                        db.ExecuteNonQuery(q1);
                                    }
                                }
                                ProgressbarCounter++;
                            }
                            #endregion

                            #region Ways and buildings
                            if (reader.Name == "way")
                            {
                                idParentNode = reader.GetAttribute("id");
                                string q = "INSERT INTO ways (id) VALUES (\"" + idParentNode + "\");";
                                db.ExecuteNonQuery(q);
                                int nodesCounter = 1;

                                XmlReader readerChilds = reader.ReadSubtree();

                                while (readerChilds.Read())
                                {
                                    if (readerChilds.Name == "tag")
                                    {
                                        string key = readerChilds.GetAttribute("k").Replace("\"", "").Replace("'", "''");
                                        string value = readerChilds.GetAttribute("v").Replace("\"", "").Replace("'", "''");

                                        string q1 = "INSERT INTO way_tags (ref, key, value) VALUES (\"" + idParentNode + "\",\"" + key + "\",\"" + value + "\");";
                                        db.ExecuteNonQuery(q1);

                                        if (key == "highway")
                                        {
                                            string q6 = "UPDATE ways_full SET type = 'highway', subtype = '" + value + "' WHERE id_way = '" + idParentNode + "';";
                                            swStep2.WriteLine(q6);
                                            step2Counter++;
                                        }

                                        if (key == "building")
                                        {
                                            string q7 = "UPDATE ways_full SET type = 'building' WHERE id_way = '" + idParentNode + "';";
                                            swStep2.WriteLine(q7);
                                            step2Counter++;
                                        }

                                        if (key == "name")
                                        {
                                            string q8 = "UPDATE ways_full SET name = '" + value + "' WHERE id_way = '" + idParentNode + "';";
                                            swStep2.WriteLine(q8);
                                            step2Counter++;
                                        }
                                    }

                                    if (readerChilds.Name == "nd")
                                    {
                                        string idNode = readerChilds.GetAttribute("ref").Replace("\"", "");
                                        string q2 = "INSERT INTO way_nodes (way, num, node) VALUES (\"" + idParentNode + "\",\"" + nodesCounter + "\",\"" + idNode + "\");";
                                        db.ExecuteNonQuery(q2);


                                        string q5 = "INSERT INTO ways_full (id_way, id_node, num) VALUES (";
                                        q5 += "\"" + idParentNode + "\", ";
                                        q5 += "\"" + idNode + "\", ";
                                        q5 += "\"" + nodesCounter + "\" ";
                                        q5 += ");";

                                        //string queryInsertWaysFull = "UPDATE ways_full SET node_lat = '" + lat + "', node_lon = '" + lon + "' WHERE id_way = '" + tmp["id_way"] + "' AND id_node = '" + tmp["id_node"] + "';";
                                        swStep1.WriteLine(q5);
                                        step1Counter++;
                                        nodesCounter++;

                                    }
                                }

                                ProgressbarCounter++;
                            }
                            #endregion
                        }
                    }

                    #endregion

                    #region Closing files
                    swStep1.Close();
                    swStep2.Close();
                    #endregion

                    #region Closing Transaction
                    db.EndTransaction();
                    #endregion

                    #region Transaction Step 1
                    db.BeginTransaction();
                    db.ExecuteNonQuery("DELETE FROM ways_full;");

                    StreamReader srStep1 = new StreamReader(Settings.BulkSQL_Step1_Path);
                    string line;

                    SetLabelMessage_LoadFile("Post processing STEP 1, wait please...");
                    SetProgressbar_LoadFile(0);
                    SetProgressbarMaximum_LoadFile(step1Counter);
                    int counterProgressbarStep1 = 0;

                    while ((line = srStep1.ReadLine()) != null)
                    {
                        db.ExecuteNonQuery(line);
                        SetProgressbar_LoadFile(counterProgressbarStep1++);
                    }

                    db.EndTransaction();
                    #endregion

                    #region Transaction Step 2
                    db.BeginTransaction();

                    StreamReader srStep2 = new StreamReader(Settings.BulkSQL_Step2_Path);

                    SetLabelMessage_LoadFile("Post processing STEP 2, wait please...");
                    SetProgressbar_LoadFile(0);
                    SetProgressbarMaximum_LoadFile(step2Counter);
                    int counterProgressbarStep2 = 0;

                    while ((line = srStep2.ReadLine()) != null)
                    {
                        db.ExecuteNonQuery(line);
                        SetProgressbar_LoadFile(counterProgressbarStep2++);
                    }

                    db.EndTransaction();
                    #endregion

                    TimeSpan elapsedTime = DateTime.Now - startTime;
                    MessageBox.Show("Elapsed importing TIME: " + elapsedTime);

                    #region Reset controls
                    SetProgressbar_LoadFile(0);
                    SetButtonGO_LoadFile_enabled(true);
                    SetButtonStop_LoadFile_Enabled(false);
                    SetLabelMessage_LoadFile("Press button to GO!...");
                    #endregion
                }
                catch (Exception ex)
                {
                    Log(ex.ToString() + "\n\rNODE: " + ProgressbarCounter);
                    SetProgressbar_LoadFile(0);
                    SetButtonGO_LoadFile_enabled(true);
                    SetButtonStop_LoadFile_Enabled(false);
                    SetLabelMessage_LoadFile("Error, check error LOG...");
                }
            }
        }
        private void Load_OSM_File_Into_DB_OLD()
        {
            int contatoreProgressbar = 0;

            if (!this.DesignMode)
            {
                try
                {
                    db.Connect();
                    db.BeginTransaction();
                    db.ExecuteNonQuery("DELETE FROM ways_full;");
                    db.ExecuteNonQuery("DELETE FROM nodes;");
                    db.ExecuteNonQuery("DELETE FROM ways;");
                    db.ExecuteNonQuery("DELETE FROM node_tags;");
                    db.ExecuteNonQuery("DELETE FROM way_tags;");
                    db.ExecuteNonQuery("DELETE FROM way_nodes;");

                    SetLabelMessage_LoadFile("Estimating time to finish...");
                    int nodiTotali = File_OSM_Statistics();
                    SetProgressbarMaximum_LoadFile(nodiTotali);
                    SetLabelNodesCount_LoadFile("Nodes count: 0/" + nodiTotali.ToString());

                    SetLabelMessage_LoadFile("Loading file into DB...");
                    XmlReader reader = XmlReader.Create(textBoxPathToOSMdata.Text);
                    string idParentNode = "-1";
                    DateTime startTime = DateTime.Now;

                    while (reader.Read())
                    {
                        if (((contatoreProgressbar % 100) == 1) || (contatoreProgressbar >= progressBarGO_LoadFile.Maximum))
                        {
                            SetProgressbar_LoadFile(contatoreProgressbar);
                            TimeSpan timeLocalExecution = DateTime.Now - startTime;
                            long totalTicks = nodiTotali * timeLocalExecution.Ticks / contatoreProgressbar;
                            long ticksToFinish = totalTicks - timeLocalExecution.Ticks;
                            TimeSpan timeToFinish = new TimeSpan(ticksToFinish);
                            SetLabelTimeToFinish_LoadFile("Estimated time to finish: " + timeToFinish.ToString());
                            SetLabelNodesCount_LoadFile("Nodes count: " + contatoreProgressbar + "/" + nodiTotali.ToString());
                        }

                        switch (reader.NodeType)
                        {
                            case XmlNodeType.Element:

                                if (reader.Name == "node")
                                {
                                    idParentNode = reader.GetAttribute("id");
                                    string lon = reader.GetAttribute("lon");
                                    string lat = reader.GetAttribute("lat");

                                    string q = "INSERT INTO nodes (id, lon, lat) VALUES (\"" + idParentNode + "\",\"" + lon + "\",\"" + lat + "\");";
                                    db.ExecuteNonQuery(q);

                                    XmlReader readerChilds = reader.ReadSubtree();

                                    while (readerChilds.Read())
                                    {
                                        if (readerChilds.Name == "tag")
                                        {
                                            string q1 = "INSERT INTO node_tags (ref, key, value) VALUES (\"" + idParentNode + "\",\"" + readerChilds.GetAttribute("k").Replace("\"", "") + "\",\"" + readerChilds.GetAttribute("v").Replace("\"", "") + "\");";
                                            db.ExecuteNonQuery(q1);
                                        }
                                    }
                                    contatoreProgressbar++;
                                }

                                if (reader.Name == "way")
                                {
                                    idParentNode = reader.GetAttribute("id");
                                    string q = "INSERT INTO ways (id) VALUES (\"" + idParentNode + "\");";
                                    db.ExecuteNonQuery(q);
                                    int nodesCounter = 1;

                                    XmlReader readerChilds = reader.ReadSubtree();

                                    while (readerChilds.Read())
                                    {
                                        if (readerChilds.Name == "tag")
                                        {
                                            string q1 = "INSERT INTO way_tags (ref, key, value) VALUES (\"" + idParentNode + "\",\"" + readerChilds.GetAttribute("k").Replace("\"", "") + "\",\"" + readerChilds.GetAttribute("v").Replace("\"", "") + "\");";
                                            db.ExecuteNonQuery(q1);
                                        }

                                        if (readerChilds.Name == "nd")
                                        {
                                            string idNode = readerChilds.GetAttribute("ref").Replace("\"", "");
                                            string q2 = "INSERT INTO way_nodes (way, num, node) VALUES (\"" + idParentNode + "\",\"" + nodesCounter + "\",\"" + idNode + "\");";
                                            db.ExecuteNonQuery(q2);
                                        }
                                    }

                                    contatoreProgressbar++;
                                }

                                //if (reader.Name == "relation")
                                //{
                                //    idParentNode = reader.GetAttribute("id").Replace("\"", "");
                                //    db.ExecuteNonQuery("INSERT INTO relations (id, user, timestamp, marked) VALUES (\"" + idParentNode + "\",\"" + reader.GetAttribute("user").Replace("\"", "") + "\",\"" + reader.GetAttribute("timestamp").Replace("\"", "") + "\",\"\")");
                                //    contatoreNodi_RELATION++;

                                //    XmlReader readerChilds = reader.ReadSubtree();
                                //    while (readerChilds.Read())
                                //        if (readerChilds.Name == "tag")
                                //            db.ExecuteNonQuery("INSERT INTO relation_tags (ref, key, value, marked) VALUES (\"" + idParentNode + "\",\"" + readerChilds.GetAttribute("k").Replace("\"", "") + "\",\"" + readerChilds.GetAttribute("v").Replace("\"", "") + "\",\"\")");

                                //}
                                break;
                            case XmlNodeType.Text:
                                break;
                            case XmlNodeType.XmlDeclaration:
                            case XmlNodeType.ProcessingInstruction:
                                break;
                            case XmlNodeType.Comment:
                                break;
                            case XmlNodeType.EndElement:
                                break;
                        }
                    }

                    db.EndTransaction();

                    SetProgressbar_LoadFile(0);
                    SetButtonGO_LoadFile_enabled(true);
                    SetButtonStop_LoadFile_Enabled(false);
                    SetLabelMessage_LoadFile("Press button to GO!...");
                }
                catch (Exception ex)
                {
                    Log(ex.ToString() + "\n\rNODE: " + contatoreProgressbar);
                    SetProgressbar_LoadFile(0);
                    SetButtonGO_LoadFile_enabled(true);
                    SetButtonStop_LoadFile_Enabled(false);
                    SetLabelMessage_LoadFile("Error, check error LOG...");
                }
            }
        }
        private void ConvertingTables()
        {
            int contatoreProgressbar = 0;

            if (!this.DesignMode)
            {
                try
                {
                    DateTime startTime = DateTime.Now;
                    db.Connect();

                    StreamWriter sw = new StreamWriter(Settings.BulkSQL_Path);

                    SetButtonStop_ConvertTables_Enabled(true);
                    SetButtonGO_ConvertTables_enabled(false);
                    SetLabelMessage_ConvertTables("Coverting tables in progress...");

                    string queryWays = "SELECT count(*) AS count FROM way_nodes "; //LIMIT 100000 OFFSET 0";
                    DataTable resultDataTableWays = db.ExecuteQuery(queryWays);
                    int numberOfRecords = int.Parse(resultDataTableWays.Rows[0]["count"].ToString());

                    SetProgressbarMaximum_ConvertTables(numberOfRecords);

                    string queryWaysFull = "SELECT * FROM way_nodes "; //LIMIT 100000 OFFSET 0";
                    SQLiteDataReader dataReader_WayNodes = db.ExecuteQueryAndPassMeTheReader(queryWaysFull);
                    SetLabelMessage_ConvertTables("Inserting nodes coordinates, please wait...");

                    while (dataReader_WayNodes.Read())
                    {
                        string node = dataReader_WayNodes.GetInt64(2).ToString();
                        string way = dataReader_WayNodes.GetInt64(0).ToString();

                        string querySelectNode = "SELECT lon, lat FROM nodes WHERE id = '" + node + "';";
                        SQLiteDataReader dataReader_Node = db.ExecuteQueryAndPassMeTheReader(querySelectNode);

                        if (dataReader_Node.Read())
                        {
                            string lat = dataReader_Node.GetDouble(1).ToString().Replace(",", ".");
                            string lon = dataReader_Node.GetDouble(0).ToString().Replace(",", ".");

                            string q5 = "INSERT INTO ways_full (id_way, id_node, node_lat, node_lon) VALUES (";
                            q5 += "\"" + way + "\", ";
                            q5 += "\"" + node + "\", ";
                            q5 += "\"" + lat + "\", ";
                            q5 += "\"" + lon + "\" ";
                            q5 += ");";

                            //string queryInsertWaysFull = "UPDATE ways_full SET node_lat = '" + lat + "', node_lon = '" + lon + "' WHERE id_way = '" + tmp["id_way"] + "' AND id_node = '" + tmp["id_node"] + "';";
                            sw.WriteLine(q5);

                            SetProgressbar_ConvertTables(contatoreProgressbar++);
                        }

                    }

                    dataReader_WayNodes = db.ExecuteQueryAndPassMeTheReader(queryWaysFull);
                    contatoreProgressbar = 0;
                    SetLabelMessage_ConvertTables("Inserting names, types and buildings, please wait...");

                    while (dataReader_WayNodes.Read())
                    {
                        string node = dataReader_WayNodes.GetInt64(2).ToString();
                        string way = dataReader_WayNodes.GetInt64(0).ToString();

                        string querySelectTags = "SELECT key, value FROM way_tags WHERE ref = '" + way + "';";
                        SQLiteDataReader dataReader_WayTags = db.ExecuteQueryAndPassMeTheReader(querySelectTags);

                        while (dataReader_WayTags.Read())
                        {
                            string key = dataReader_WayTags.GetString(0).Trim().Replace("'", "''");
                            string value = dataReader_WayTags.GetString(1).Trim().Replace("'", "''");

                            if (key == "highway")
                            {
                                string q6 = "UPDATE ways_full SET type = 'highway', subtype = '" + value + "' WHERE id_way = '" + way + "' AND id_node = '" + node + "';";
                                sw.WriteLine(q6);
                            }

                            if (key == "building")
                            {
                                string q7 = "UPDATE ways_full SET type = 'building' WHERE id_way = '" + way + "' AND id_node = '" + node + "';";
                                sw.WriteLine(q7);
                            }

                            if (key == "name")
                            {
                                string q8 = "UPDATE ways_full SET name = '" + value + "' WHERE id_way = '" + way + "' AND id_node = '" + node + "';";
                                sw.WriteLine(q8);
                            }
                        }

                        SetProgressbar_ConvertTables(contatoreProgressbar++);
                    }

                    sw.Close();




                    db.BeginTransaction();
                    db.ExecuteNonQuery("DELETE FROM ways_full;");

                    StreamReader sr = new StreamReader(Settings.BulkSQL_Path);
                    string line;

                    while ((line = sr.ReadLine()) != null)
                        db.ExecuteNonQuery(line);

                    db.EndTransaction();

                    TimeSpan elapsedTime = DateTime.Now - startTime;
                    MessageBox.Show("Elapsed: " + elapsedTime);


                    SetProgressbar_ConvertTables(0);
                    SetButtonGO_ConvertTables_enabled(true);
                    SetButtonStop_ConvertTables_Enabled(false);
                    SetLabelMessage_ConvertTables("Press button to GO!...");
                }
                catch (Exception ex)
                {
                    Log(ex.ToString() + "\n\rNODE: " + contatoreProgressbar);
                    SetProgressbar_ConvertTables(0);
                    SetButtonGO_ConvertTables_enabled(true);
                    SetButtonStop_ConvertTables_Enabled(false);
                    SetLabelMessage_ConvertTables("Error, check error LOG!...");
                }
            }
        }
        private void ConvertingTables_OLD()
        {
            int contatoreProgressbar = 0;

            if (!this.DesignMode)
            {
                try
                {
                    db.Connect();

                    StreamWriter sw = new StreamWriter(Settings.BulkSQL_Path);

                    SetButtonStop_ConvertTables_Enabled(true);
                    SetButtonGO_ConvertTables_enabled(false);
                    SetLabelMessage_ConvertTables("Coverting tables in progress...");

                    string queryWays = "SELECT count(*) AS count FROM way_nodes "; //LIMIT 100000 OFFSET 0";
                    DataTable resultDataTableWays = db.ExecuteQuery(queryWays);
                    int numberOfRecords = int.Parse(resultDataTableWays.Rows[0]["count"].ToString());
                    int step = 100000;

                    //SELECT key, count(key) as quanti FROM way_tags GROUP BY key ORDER BY 2 DESC
                    //SELECT key, count(key) as quanti FROM node_tags GROUP BY key ORDER BY 2 DESC

                    SetProgressbarMaximum_ConvertTables(numberOfRecords);

                    for (int c = 0; c < numberOfRecords; c += step)
                    {
                        contatoreProgressbar = c;
                        SetProgressbar_ConvertTables(contatoreProgressbar);

                        int offset = c;

                        queryWays = "SELECT way, node FROM way_nodes LIMIT " + step + " OFFSET " + c;
                        resultDataTableWays = db.ExecuteQuery(queryWays);

                        foreach (DataRow tmp in resultDataTableWays.Rows)
                        {
                            string querySelectNodes = "SELECT lon, lat FROM nodes WHERE id = '" + tmp["node"] + "';";
                            DataTable resultDataTableNode = db.ExecuteQuery(querySelectNodes);

                            if (resultDataTableNode.Rows.Count > 0)
                            {
                                string lat = resultDataTableNode.Rows[0]["lat"].ToString().Replace(",", ".");
                                string lon = resultDataTableNode.Rows[0]["lon"].ToString().Replace(",", ".");

                                string q5 = "INSERT INTO ways_full (id_way, id_node, node_lat, node_lon) VALUES (";
                                q5 += "\"" + tmp["way"] + "\", ";
                                q5 += "\"" + tmp["node"] + "\", ";
                                q5 += "\"" + lat + "\", ";
                                q5 += "\"" + lon + "\" ";
                                q5 += ");";

                                //string queryInsertWaysFull = "UPDATE ways_full SET node_lat = '" + lat + "', node_lon = '" + lon + "' WHERE id_way = '" + tmp["id_way"] + "' AND id_node = '" + tmp["id_node"] + "';";
                                sw.WriteLine(q5);

                                //SELECT * from way_tags WHERE key = 'highway' GROUP BY value
                                string querySelectTags = "SELECT * FROM way_tags WHERE ref = '" + tmp["way"] + "';";
                                DataTable resultDataTableWay = db.ExecuteQuery(querySelectTags);

                                foreach (DataRow rowTags in resultDataTableWay.Rows)
                                {
                                    string key = rowTags["key"].ToString().Trim();
                                    string value = rowTags["value"].ToString().Trim().Replace("'", "''");

                                    if (key == "highway")
                                    {
                                        string q6 = "UPDATE ways_full SET type = 'highway', subtype = '" + value + "' WHERE id_way = '" + tmp["way"] + "' AND id_node = '" + tmp["node"] + "';";
                                        sw.WriteLine(q6);
                                    }

                                    if (key == "building")
                                    {
                                        string q6 = "UPDATE ways_full SET type = 'building' WHERE id_way = '" + tmp["way"] + "' AND id_node = '" + tmp["node"] + "';";
                                        sw.WriteLine(q6);
                                    }

                                    if (key == "name")
                                    {
                                        string q7 = "UPDATE ways_full SET name = '" + value + "' WHERE id_way = '" + tmp["way"] + "' AND id_node = '" + tmp["node"] + "';";
                                        sw.WriteLine(q7);
                                    }
                                }
                            }
                        }
                    }

                    sw.Close();

                    db.BeginTransaction();
                    db.ExecuteNonQuery("DELETE FROM ways_full;");

                    StreamReader sr = new StreamReader(Settings.BulkSQL_Path);
                    string line;

                    while ((line = sr.ReadLine()) != null)
                        db.ExecuteNonQuery(line);

                    db.EndTransaction();

                    SetProgressbar_ConvertTables(0);
                    SetButtonGO_ConvertTables_enabled(true);
                    SetButtonStop_ConvertTables_Enabled(false);
                    SetLabelMessage_ConvertTables("Press button to GO!...");
                }
                catch (Exception ex)
                {
                    Log(ex.ToString() + "\n\rNODE: " + contatoreProgressbar);
                    SetProgressbar_ConvertTables(0);
                    SetButtonGO_ConvertTables_enabled(true);
                    SetButtonStop_ConvertTables_Enabled(false);
                    SetLabelMessage_ConvertTables("Error, check error LOG!...");
                }
            }
        }
        private int File_OSM_Statistics()
        {
            int counter = 0;
            XmlReader reader = XmlReader.Create(textBoxPathToOSMdata.Text);

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (reader.Name == "node") counter++;
                        if (reader.Name == "way") counter++;
                        break;
                }
            }

            return counter;
        }
        private void ImportKML(string path)
        {
            System.Globalization.CultureInfo NmeaCultureInfo = new System.Globalization.CultureInfo("en-US");

            XmlDocument xdoc = new XmlDocument();
            xdoc.Load("route.kml");

            XmlNode rootNode = xdoc.SelectSingleNode("/");
            XmlNode KmlNode = rootNode.ChildNodes[1];
            XmlNode DocumentNode = KmlNode.ChildNodes[0];

            XmlNodeList nodes = DocumentNode.ChildNodes;

            StreamWriter swFileNMEA = new StreamWriter(Settings.NMEA_path);
            swFileNMEA.WriteLine("$GPGSV,3,1,12,16,69,216,25,06,63,303,15,01,54,181,34,21,49,058,27*7C");


            foreach (XmlNode tmp in nodes)
            {
                if (tmp.Name == "Placemark")
                {
                    XmlNode point = tmp.ChildNodes[1];
                    XmlNode coordinate = point.ChildNodes[0];

                    string coordinateTxt = coordinate.InnerText.Replace(",0", "");
                    string[] LonLat = coordinateTxt.Split(' ');

                    double lon = double.Parse(LonLat[0], NmeaCultureInfo);
                    double lat = double.Parse(LonLat[1], NmeaCultureInfo);

                    string NMEArow = "$GPRMC,144651.506,A,";

                    string NMEAlatitudeString = GlobalFunctions.DecimalDegreesToGPS(lat, false) + ",";
                    string NMEAlongitudeString = GlobalFunctions.DecimalDegreesToGPS(lon, true) + ",";
                    string NMEAspeedString = "000.0,";
                    string NMEAdirectionString = "128.1,";
                    string NMEAdateString = "031010,,*1A";

                    NMEArow += NMEAlatitudeString + NMEAlongitudeString + NMEAspeedString + NMEAdirectionString + NMEAdateString;

                    swFileNMEA.WriteLine(NMEArow);

                    //  KML:  <coordinates>9.181191 45.469017,0</coordinates>
                    //  NMEA: 9° 10' 52.2876"   45° 28' 8.4612"

                    //  $GPRMC,040302.663,A,4529.5,N,914.3,E,0.27,358.86,200804,,*1A
                    //  $GPRMC,144651.506,A,4529.4504,N,00914.1955,E,000.0,128.1,031010,,,A*6C
                    //  $GPRMC, 144651.506, A, 4529.4504, N, 00914.1955, E, 000.0, 128.1, 031010, , , A*6C
                    //           
                }
            }

            swFileNMEA.Close();
        }

        //GPS - FTP MAPS
        private FtpClient ftpClient = new FtpClient();
        private FtpServer ftpServer = new FtpServer();
        private string ftpPathOnServer = "/www.onlyonemillion.com/stone/maps";
        private long MAX_CHUNK_SIZE = 200;
        private string OSM_MAP_FILENAME = "db";

        private void button_Gps_Map_Download_Click(object sender, EventArgs e)
        {

        }
        private void button_Gps_Map_Upload_Click(object sender, EventArgs e)
        {
            if (null != treeView_Gps_Ftp_Client.SelectedNode)
            {
                MapDescription mapDescription = (MapDescription)treeView_Gps_Ftp_Client.SelectedNode.Tag;

                if (null != mapDescription)
                {
                    ftpClient.ChangeDir(ftpPathOnServer);
                    ftpClient.MakeDir(mapDescription.name);
                    ftpClient.ChangeDir(mapDescription.name);
                    serializeMapDescription(Settings.Ftp_MapDescriptionTmp_Path, mapDescription);
                    uploadFile(Settings.Ftp_MapDescriptionTmp_Path, ftpPathOnServer + "/" + mapDescription.name + "/" + "MapDescription.xml", false);

                    string currentDirectoryOnServer = ftpPathOnServer + "/" + mapDescription.name;
                    string currentDirectoryOnClient = Settings.Maps_Path + "\\" + mapDescription.name;
                    //UPLOAD FILE CHUNKED
                    //uploadFileChunked(Settings.Ftp_MapDescriptionTmp_Path, Settings.Maps_Path + "\\" + mapDescription.name, true);
                    uploadFile(currentDirectoryOnClient + "\\" + OSM_MAP_FILENAME, currentDirectoryOnServer + "/" + OSM_MAP_FILENAME, false);
                    FtpRefreshServerList();

                }
            }
        }
        private void treeView_Gps_Ftp_Server_Click(object sender, EventArgs e)
        {
            ServerListNodeSelected();
        }
        private void treeView_Gps_Ftp_Client_Click(object sender, EventArgs e)
        {
            ClientListNodeSelected();
        }
        private void treeView_Gps_Ftp_Server_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            ServerListNodeSelected();
        }
        private void treeView_Gps_Ftp_Client_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            ClientListNodeSelected();
        }
        private void treeView_Gps_Ftp_Server_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ServerListNodeSelected();
        }
        private void treeView_Gps_Ftp_Client_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ClientListNodeSelected();
        }

        private void ClientListNodeSelected()
        {
            button_Gps_Map_Download.Enabled = false;
            button_Gps_Map_Upload.Enabled = false;

            if (null != treeView_Gps_Ftp_Client.SelectedNode)
            {
                MapDescription mapDescription = (MapDescription)treeView_Gps_Ftp_Client.SelectedNode.Tag;

                if (null != mapDescription)
                {
                    if (mapDescription.status == "available")
                    {
                        button_Gps_Map_Upload.Enabled = true;
                    }
                }
            }
        }
        private void ServerListNodeSelected()
        {
            button_Gps_Map_Download.Enabled = false;
            button_Gps_Map_Upload.Enabled = false;

            if (null != treeView_Gps_Ftp_Server.SelectedNode)
            {
                MapDescription mapDescription = (MapDescription)treeView_Gps_Ftp_Server.SelectedNode.Tag;

                if (null != mapDescription)
                {
                    if (mapDescription.status == "available")
                    {
                        button_Gps_Map_Download.Enabled = true;
                    }
                }
            }
        }
        private void FtpConnect(FtpServer s)
        {
            try
            {
                ftpClient.Connect(s.url, s.username, s.password);

                if (ftpClient.IsConnected)
                {
                    ftpClient.ChangeDir(ftpPathOnServer);
                    this.pictureBox_Gps_FtpServer_Status.BackgroundImage = global::Stone.Properties.Resources.ServerFtpConnected;
                    label_Gps_Ftp_ServerStatus.Text = "Server connected";
                    FtpRefreshServerList();
                }
                else
                {
                    this.pictureBox_Gps_FtpServer_Status.BackgroundImage = global::Stone.Properties.Resources.ServerFtpDisconnected;
                    label_Gps_Ftp_ServerStatus.Text = "Server disconnected";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void FtpDisconnect()
        {
            try
            {
                this.pictureBox_Gps_FtpServer_Status.BackgroundImage = global::Stone.Properties.Resources.ServerFtpDisconnected;
                label_Gps_Ftp_ServerStatus.Text = "Server disconnected";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void FtpRefreshClientList()
        {
            DirectoryInfo d = new DirectoryInfo(Settings.Maps_Path);

            TreeNode nuovoNodo;
            treeView_Gps_Ftp_Client.Nodes.Clear();
            DirectoryInfo[] directoryList = d.GetDirectories();

            foreach (DirectoryInfo tmpDirectory in directoryList)
            {
                if ((tmpDirectory.Name != ".") && (tmpDirectory.Name != ".."))
                {
                    FileInfo[] fileList = tmpDirectory.GetFiles();
                    MapDescription tmpMapDescription = null;

                    foreach (FileInfo tmpFile in fileList)
                    {
                        if (tmpFile.Name == "MapDescription.xml")
                        {
                            tmpMapDescription = deserializeMapDescription(tmpFile.FullName);
                        }
                    }

                    nuovoNodo = new TreeNode(printMapDescription(tmpMapDescription), 4, 4);
                    nuovoNodo.Tag = tmpMapDescription;
                    treeView_Gps_Ftp_Client.Nodes.Add(nuovoNodo);
                }
            }
        }
        private void FtpRefreshServerList()
        {
            if (ftpClient.IsConnected)
            {
                ftpClient.ChangeDir(ftpPathOnServer);

                TreeNode nuovoNodo;
                treeView_Gps_Ftp_Server.Nodes.Clear();
                ArrayList directoryList = ftpClient.ListDirectories();

                foreach (FTP_file tmpDirectory in directoryList)
                {
                    if ((tmpDirectory.nome != ".") && (tmpDirectory.nome != ".."))
                    {
                        string currentDirectoryOnServer = ftpPathOnServer + "/" + tmpDirectory.nome;
                        ftpClient.ChangeDir(currentDirectoryOnServer);
                        ArrayList fileList = ftpClient.ListFiles();
                        MapDescription tmpMapDescription = null;

                        foreach (FTP_file tmpFile in fileList)
                        {
                            if (tmpFile.nome == "MapDescription.xml")
                            {
                                downloadFile(currentDirectoryOnServer + "/" + tmpFile.nome, Settings.Ftp_MapDescriptionTmp_Path, false);
                                tmpMapDescription = deserializeMapDescription(Settings.Ftp_MapDescriptionTmp_Path);
                            }
                        }

                        nuovoNodo = new TreeNode(printMapDescription(tmpMapDescription), 4, 4);
                        nuovoNodo.Tag = tmpMapDescription;
                        treeView_Gps_Ftp_Server.Nodes.Add(nuovoNodo);
                    }
                }

                ftpClient.ChangeDir(ftpPathOnServer);
            }
        }
        private string printMapDescription(MapDescription tmpMapDescription)
        {
            if (null != tmpMapDescription)
                return tmpMapDescription.name + " - " + tmpMapDescription.size + " Bytes - " + tmpMapDescription.lastUpdate + " - Status: " + tmpMapDescription.status;
            else
                return "Error!";
        }
        public void serializeMapDescription(string path, MapDescription mapDescriptionToSerialize)
        {
            try
            {
                XmlSerializer s = new XmlSerializer(typeof(MapDescription));
                TextWriter w = new StreamWriter(path);
                s.Serialize(w, mapDescriptionToSerialize);
                w.Close();
            }
            catch (Exception ex)
            {
                Log("serializeMapDescription(\"" + path + "\")" + ex.ToString());
            }
        }
        public MapDescription deserializeMapDescription(string path)
        {
            MapDescription result = null;

            try
            {
                if (File.Exists(path))
                {
                    XmlSerializer s = new XmlSerializer(typeof(MapDescription));
                    TextReader r = new StreamReader(path);
                    result = (MapDescription)s.Deserialize(r);
                    r.Close();
                    r.Dispose();
                }
            }
            catch (Exception ex)
            {
                Log("deserializeMapDescription(\"" + path + "\")" + ex.ToString());
            }

            return result;
        }
        //public void downloadFile(FileFtp fileDaGestire, string pathLocale, Task taskDaEseguire)
        //{
        //    TreeNode nodoContenenteIlTaskDaEseguire = cercaNodoConIlSeguenteTaskNelTreeview(taskDaEseguire, treeViewCoda);

        //    try
        //    {
        //        int perc = 0;

        //        if (!ftpClient.IsConnected)
        //        {
        //            MessageBox.Show("Non si è connessi a nessun server!");
        //            return;
        //        }

        //        ftpClient.OpenDownload(fileDaGestire.path, pathLocale, true);

        //        while (ftpClient.DoDownload() > 0)
        //        {
        //            perc = (int)(((ftpClient.BytesTotal) * 100) / ftpClient.FileSize);
        //            taskDaEseguire.PercentualeCompletamento = perc;
        //            aggiornaTaskNelTreeview(taskDaEseguire);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        MessageBox.Show(ex.ToString());
        //    }
        //}
        public void downloadFile(string pathFileRemoto, string pathFileLocale, bool resume)
        {
            try
            {
                //int perc = 0;
                ftpClient.OpenDownload(pathFileRemoto, pathFileLocale, resume);

                while (ftpClient.DoDownload() > 0)
                {
                    //perc = (int)(((ftpClient.BytesTotal) * 100) / ftpClient.FileSize);
                    //taskDaEseguire.PercentualeCompletamento = perc;
                    //aggiornaTaskNelTreeview(taskDaEseguire);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void uploadFile(string pathFileLocale, string pathFileRemoto, bool resume)
        {
            try
            {
                progressBar_Ftp_Download_Upload.Minimum = 0;
                progressBar_Ftp_Download_Upload.Maximum = 100;

                ftpClient.OpenUpload(pathFileLocale, pathFileRemoto, resume);

                while (ftpClient.DoUpload(0) > 0)
                {
                    int percent = (int)(((ftpClient.BytesTotal) * 100) / ftpClient.FileSize);
                    progressBar_Ftp_Download_Upload.Refresh();
                    progressBar_Ftp_Download_Upload.Value = percent;
                    progressBar_Ftp_Download_Upload.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBar_Ftp_Download_Upload.Width / 2 - 10, progressBar_Ftp_Download_Upload.Height / 2 - 7));
                }

                progressBar_Ftp_Download_Upload.Value = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void uploadFileChunked(string pathFileLocale, string pathFileRemoto, bool resume)
        {
            //try
            //{
            //    bool finished = false;
            //    FileInfo localFileInfo = new FileInfo(pathFileLocale);

            //    long localFileSize = localFileInfo.Length;
            //    long localFileStartByte = 0;
            //    long localFileStopByte = 0;
            //    long serverFileStartByte = 0;
            //    long serverFileStopByte = 0;

            //    while (!finished)
            //    {                    
            //        if (localFileSize > localFileStartByte)
            //        {
            //            ftpClient.OpenUpload(pathFileLocale, pathFileRemoto, resume, localFileStartByte, localFileStopByte, serverFileStartByte, serverFileStopByte);
            //            long bytesGot = 1;
            //            long localFileCurrentPosition = 0;

            //            while (bytesGot > 0)
            //            {
            //                bytesGot = ftpClient.DoUpload(localFileStartByte);
            //                localFileCurrentPosition += bytesGot;
            //            }

            //        }
            //        else
            //            finished = true;

            //        localFileStartByte += MAX_CHUNK_SIZE;
            //        localFileStopByte = localFileStartByte + MAX_CHUNK_SIZE;

            //        if (localFileStopByte > localFileSize)
            //            localFileStopByte = localFileSize;
            //    }
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.ToString());
            //}
        }
    }
}
